package com.xnyzc.lhy.didi.service.impl.xiecheng;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.MqConstant;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.Qw;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.entity.order.OaDOrderCharteredDetail;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.order.CharteredOrderStatus;
import com.xnyzc.lhy.common.penum.order.EOrderStatus;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.http.HttpRequestUtil;
import com.xnyzc.lhy.didi.common.constants.EXieChengResponseConstant;
import com.xnyzc.lhy.didi.entity.order.OaCOrderPersonal;
import com.xnyzc.lhy.didi.entity.param.synchronization.StatusCallbackParam;
import com.xnyzc.lhy.didi.entity.param.xiecheng.request.*;
import com.xnyzc.lhy.didi.entity.param.xiecheng.request.chatered.CharteredPushDriver;
import com.xnyzc.lhy.didi.entity.param.xiecheng.request.chatered.PayAdditionalFeeDTO;
import com.xnyzc.lhy.didi.entity.param.xiecheng.response.OrderDetailResponse;
import com.xnyzc.lhy.didi.entity.param.xiecheng.response.XieChengResponse;
import com.xnyzc.lhy.didi.mapper.order.OaCOrderPersonalMapper;
import com.xnyzc.lhy.didi.mapper.order.OaDOrderCharterDetailMapper;
import com.xnyzc.lhy.didi.mapper.order.OaDOrderMapper;
import com.xnyzc.lhy.didi.mapper.other.OaDUserInfoMapper;
import com.xnyzc.lhy.didi.mapper.other.OaDUserMapper;
import com.xnyzc.lhy.didi.mapper.sys.OaSysOfficeMapper;
import com.xnyzc.lhy.didi.mq.MQProducer;
import com.xnyzc.lhy.didi.service.xiecheng.XcOrderStatusSyncService;
import com.xnyzc.lhy.didi.util.XieChengUtil;
import com.xnyzc.lhy.order.entity.sidebar.OaSysOffice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class XcOrderStatusSyncServiceImpl implements XcOrderStatusSyncService {

    //供应商ID
    @Value("${global.xc.venderId}")
    private String venderId;

    //包车供应商ID
    @Value("${global.xc.CharteredVenderId:1001108}")
    private String CharteredVenderId;

    //渠道
    @Value("${global.xc.channel}")
    private String channel;

    //版本
    @Value("${global.xc.version}")
    private String version;

    //携程密钥
    @Value("${global.xc.secretKey}")
    private String secretKey;
    //包车
    @Value("${global.xc.CharteredSecretKey:12345678}")
    private String CharteredSecretKey;

    @Value("${global.xc.callback}")
    private String callback;

    @Value("${global.xc.charteredCallback}")
    private String charteredCallback;

    @Autowired
    private OaSysOfficeMapper oaSysOfficeMapper;

    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;

    @Autowired
    private OaDUserInfoMapper oaDUserInfoMapper;

    @Autowired
    private RedisCommon redisCommon;

    @Autowired
    private MQProducer producer;
    @Autowired
    private OaDOrderCharterDetailMapper oaDOrderCharterDetailMapper;
    @Autowired
    private OaDOrderMapper oaDOrderMapper;
    @Autowired
    private OaDUserMapper oaDUserMapper;
    @Autowired
    private XcCharteredServiceImpl xcCharteredService;


    @Override
    public Rv handle(StatusCallbackParam statusCallbackParam) {
        String orderId = statusCallbackParam.getOrder_id();
        OaCOrderPersonal personal = oaCOrderPersonalMapper.selectOne(Qw.create().eq(OaCOrderPersonal.ORDER_NO, orderId));
        if (personal == null) {
            return Rv.error(EErrorCode.unOrder);
        }
        String personalId = personal.getPersonalId().toString();
        if (statusCallbackParam.getOrderTpye() != null && statusCallbackParam.getOrderTpye() == 7) {
            CharteredOrderStatus status = CharteredOrderStatus.findById(statusCallbackParam.getStatus());
            switch (status) {
                case driverOrder:{
                    //推送司机
                    String driverId = statusCallbackParam.getDriver_id();
                    HashMap<String, String> driverInfo = oaDUserMapper.getDriverInfo(Long.parseLong(driverId));
                    CharteredPushDriver pushDriver=CharteredPushDriver.builder()
                            .driverId(driverId)
                            .driverName(driverInfo.get("driverName"))
                            .driverPhone(driverInfo.get("driverPhone"))
                            .vendorOrderId(personalId)
                            .ctripOrderId(orderId)
                            .vehicleColor(driverInfo.get("vehicleColor"))
                            .vehicleNumber(driverInfo.get("vehicleNumber"))
                            .vehicleTypeBrand(driverInfo.get("vehicleTypeBrand"))
                            .areaCode("+86")
                            .build();
                    String res = sendToXChartered(3, orderId, JSON.toJSONString(pushDriver));
                    return handleResult(res);
                }
                //包车业务
                case orderSucccess: {
                    QueryWrapper<OaDOrderCharteredDetail> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq(OaDOrderCharteredDetail.ORDER_NO, orderId);
                    List<OaDOrderCharteredDetail> ocds = oaDOrderCharterDetailMapper.selectList(queryWrapper);
                    PushCharteredStatus pcs = new PushCharteredStatus();
                    long allToutalFee = 0L, allOverTimeFee = 0L, allOverDisFee = 0L, allOtherFee = 0L, onLineTotalFee = 0L, onLineOverTimeFee = 0L,
                            onLineOverDisFee = 0L, onLineOtherFee = 0L, flagFee = 0L;
                    String detailOtherFeeDesc="",onlineOtherFeeDesc="";
                    int allOverTimeLength=0,onlineOverTimeLength=0,allOverDisLength=0,onlieOverDisLength=0;
                    BigDecimal d=new BigDecimal(100);
                    for (int i = 0; i < ocds.size(); i++) {
                        OaDOrderCharteredDetail ocd = ocds.get(i);
                        long overTimeFee = ocd.getExceedTimeCost().longValue();
                        long overdDisFee = ocd.getExceedDistanceCost().longValue();
                        long otherFee = ocd.getOtherCost().longValue();
                        long totalFee = overTimeFee + overdDisFee + otherFee;
                        flagFee+=totalFee;
                        String desc=ocd.getOtherCostDetail();
                        int overTimeLength=Integer.valueOf(ocd.getExceedTime());
                        int overDistanceLength=Integer.valueOf(ocd.getExceedDistance());
                        if (ocd.getPaymentType() == 1) {
                            //线上支付
                            onLineOverTimeFee += overTimeFee;
                            onLineOverDisFee += overdDisFee;
                            onLineOtherFee += otherFee;
                            onLineTotalFee+=totalFee;
                            onlieOverDisLength+=overDistanceLength;
                            onlineOverTimeLength+=overTimeLength;
                            onlineOtherFeeDesc+=desc+";";
                        } else {
                            allOverTimeFee+=overTimeFee;
                            allOverDisFee+=onLineOverDisFee;
                            allOtherFee+=otherFee;
                            allToutalFee+=totalFee;
                            allOverTimeLength+=overTimeLength;
                            allOverDisLength+=overDistanceLength;
                            detailOtherFeeDesc+=desc+";";
                        }
                    }
                    if (allToutalFee!=flagFee){
                        //线上支付，总计线上线下费用如果不等于线下费用，说明有线上支付费用，接口传线上支付标识
                        pcs.setAdditionalFeePayType(1);
                        pcs.setOverTimeFee(onLineOverTimeFee*100);
                        pcs.setOverDistanceFee(onLineOverDisFee*100);
                        pcs.setOtherFee(onLineOtherFee*100);
                        pcs.setTotalAdditionalFee(onLineTotalFee*100);//总费用
                        pcs.setOverTimeLength(onlineOverTimeLength);
                        pcs.setOverDistanceLength(onlieOverDisLength);
                        pcs.setOtherFeeDesc(onlineOtherFeeDesc);
                    }
                    else{
                        //如果相等，说明全都是线下支付，接口传线下支付标识
                        pcs.setAdditionalFeePayType(2);
                        /*pcs.setOverTimeFee(allOverTimeFee);
                        pcs.setOverDistanceFee(allOverDisFee);
                        pcs.setOtherFee(allOtherFee);
                        pcs.setTotalAdditionalFee(allToutalFee);//总费用
                        pcs.setOverTimeLength(allOverTimeLength);
                        pcs.setOverDistanceLength(allOverDisLength);
                        pcs.setOtherFeeDesc(detailOtherFeeDesc);*/
                    }
                    pcs.setCtripOrderId(orderId);
                    pcs.setVendorOrderId(personalId);
                    String res = sendToXChartered(7, orderId, JSON.toJSONString(pcs));
                    return handleResult(res);
                }
                default: {
                    return Rv.error(EErrorCode.statusNotFound);
                }
            }
        } else {
            EOrderStatus status = EOrderStatus.findById(statusCallbackParam.getStatus());
            switch (status) {
                case reassigned:
                case orderTimeout: {
                    return Rv.error(EErrorCode.applyAmountOperateFailure);
                }
                case driverOrder:
                case changeDriver: {
                    String driverId = statusCallbackParam.getDriver_id();
                    if (CheckUtil.strIsEmpty(driverId)) {
                        return Rv.error(EErrorCode.unOrder);
                    }
                    /*if (!driverId.equals(personal.getDriverId().toString())) {
                        return Rv.error(EErrorCode.unOrder);
                    }*/
                    Map<String, Object> driverInfo = oaDUserInfoMapper.getDriverInfo(driverId);
                    if (driverInfo.get("driverId") == null) {
                        return Rv.error(EErrorCode.unOrder);
                    }
                    //司机信息推送接口
                    PushDriverRequest request = new PushDriverRequest();
                    request.setCtripPurchaseOrderID(Long.parseLong(orderId));
                    request.setVendorOrderID(personalId);
                    request.setDriverName(driverInfo.get("driverName").toString());
                    request.setDriverPhone(driverInfo.get("driverPhone").toString());
                    request.setDriverPhoneCode("+86");
                    request.setDriverPhoneLangauge("DR-ZH");
                    request.setVehicleNumber(driverInfo.get("vehNo").toString());
                    request.setVehicleBrand(driverInfo.get("vehicleBrand").toString());
                    request.setVehicleBrandDetail(driverInfo.get("vehicleBrandDetail").toString());
                    request.setVehicleColor(driverInfo.get("vehColor").toString());
                    String res = sendToXC(2, orderId, JSON.toJSONString(request));
                    return handleResult(res);
                }
                case reservationLocation: {
                    //司机状态推送
                    PushDriverStatusRequest request = new PushDriverStatusRequest();
                    request.setCtripPurchaseOrderID(Long.parseLong(orderId));
                    request.setVendorOrderID(personalId);
                    request.setVehicleStatus(0);
                    String res = sendToXC(3, orderId, JSON.toJSONString(request));
                    return handleResult(res);
                }
                case driverArrived: {
                    //司机状态推送
                    PushDriverStatusRequest request = new PushDriverStatusRequest();
                    request.setCtripPurchaseOrderID(Long.parseLong(orderId));
                    request.setVendorOrderID(personalId);
                    request.setVehicleStatus(1);
                    String res = sendToXC(3, orderId, JSON.toJSONString(request));
                    return handleResult(res);
                }
                case duringTrip: {
                    //司机状态推送
                    PushDriverStatusRequest request = new PushDriverStatusRequest();
                    request.setCtripPurchaseOrderID(Long.parseLong(orderId));
                    request.setVendorOrderID(personalId);
                    request.setVehicleStatus(2);
                    String res = sendToXC(3, orderId, JSON.toJSONString(request));
                    return handleResult(res);
                }
                case sendBill: {
                    //订单完成
                    PushDriverStatusRequest request = new PushDriverStatusRequest();
                    request.setCtripPurchaseOrderID(Long.parseLong(orderId));
                    request.setVendorOrderID(personalId);
                    request.setVehicleStatus(3);
                    String res = sendToXC(3, orderId, JSON.toJSONString(request));
                    return handleResult(res);
                }
                case normalOrderPendingPayment: {
                    CompleteOrderRequest request = new CompleteOrderRequest();
                    request.setCtripPurchaseOrderID(Long.parseLong(orderId));
                    request.setVendorOrderID(personalId);
                    String res = sendToXC(4, orderId, JSON.toJSONString(request));
                    Rv rv = handleResult(res);
                    if (rv.getCode() == EErrorCode.success.getValue()) {
                        //检查订单支付状态-携程无支付状态同步接口，只能自行定时检查
                        statusCallbackParam.setStatus(EOrderStatus.orderStatusCheck.getType());
                        producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC, null, 5);
                    }
                    return rv;
                }
                case orderStatusCheck: {
                    OrderDetailRequest request = new OrderDetailRequest();
                    request.setCtripPurchaseOrderID(Long.parseLong(orderId));
                    request.setVendorOrderID(personalId);
                    String res = sendToXC(5, orderId, JSON.toJSONString(request));
                    OrderDetailResponse response = JSON.parseObject(res, OrderDetailResponse.class);
                    if ("OK".equalsIgnoreCase(response.getMsgCode())) {
                        if ("CANCELLED".equalsIgnoreCase(response.getOrderStatus())) {
                            personal.setOrderStatus(EOrderStatus.cancelOrderNoNeedPayment.getType());
                            personal.setCancelReason(response.getCancelDetail().getCancelReason());
                            personal.setUpdateTime(new Date());
                            if (oaCOrderPersonalMapper.updateById(personal) > 0) {
                                //删除延时任务所需数据
                                String bookingKey = RedisPrefixConstant.ORDER_BOOKING + personal.getOfficeId() + ":" + personal.getOrderNo();
                                redisCommon.remove(bookingKey);

                                redisCommon.delFromZSet(RedisPrefixConstant.ORDER_TC_HALL + personal.getCityId(), bookingKey);
                                redisCommon.delFromZSet(RedisPrefixConstant.ORDER_TC_ZSET2, bookingKey);
                                redisCommon.delFromZSet(RedisPrefixConstant.ORDER_TC_ZSET3, bookingKey);
                                redisCommon.delFromZSet(RedisPrefixConstant.ORDER_TC_ZSET4, bookingKey);
                                redisCommon.delFromZSet(RedisPrefixConstant.ORDER_TC_ZSET5, bookingKey);

                                //删除rediskey
                                String key = RedisPrefixConstant.ORDER_OA_D_ORDER + personal.getOrderNo();
                                if (redisCommon.hashKey(key)) {
                                    if (CheckUtil.objIsNotEmpty(personal.getDriverId())) {
                                        redisCommon.remove(RedisPrefixConstant.ORDER_VEH + personal.getDriverId());
                                    }
                                    if (CheckUtil.objIsNotEmpty(personal.getUserId())) {
                                        redisCommon.remove(RedisPrefixConstant.ORDER_USER + personal.getUserId());
                                    }
                                    redisCommon.remove(key);
                                }
                            }
                            return Rv.error(EErrorCode.currentOrderCancelled);
                        }
                        if ("COMPLETED".equalsIgnoreCase(response.getOrderStatus())) {
                            personal.setOrderStatus(EOrderStatus.paymented.getType());
                            oaCOrderPersonalMapper.updateById(personal);
                        }
                        return Rv.wrap();
                    } else {
                        return Rv.error(EErrorCode.gatewayDeny);
                    }
                }
                default: {
                    return Rv.error(EErrorCode.statusNotFound);
                }
            }
        }
    }

    @Override
    public Rv bindDefaultDriver(OaCOrderPersonal personal) {
        OaSysOffice company = oaSysOfficeMapper.selectOne(Qw.create().eq(OaSysOffice.OFFICE_ID, personal.getOfficeId()));

        ConfirmOrderRequest request = new ConfirmOrderRequest();
        String orderId = personal.getOrderNo();
        request.setCtripPurchaseOrderID(Long.parseLong(orderId));
        request.setVendorOrderID(String.valueOf(personal.getPersonalId()));
        request.setConnectTelCode("+86");
        request.setConnectTel(company.getPhone());
        String res = sendToXC(1, orderId, JSON.toJSONString(request));
        return handleResult(res);
    }


    @Override
    public Rv bindDefaultDriverNew(OaCOrderPersonal personal) {
        String res=null;
        if (personal.getOrderType()==7){
            res=sendToXChartered(3, personal.getOrderNo(), JSON.toJSONString(getDefaultDriver(personal)));
        }else{
            res = sendToXC(2, personal.getOrderNo(), JSON.toJSONString(getDefaultDriver(personal)));
        }
        return handleResult(res);
    }

    private String sendToXChartered(int type, String orderId, String body) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStamp = sdf.format(System.currentTimeMillis());
        log.info("XC-" + body);

        String params = "";
        try {
            params = XieChengUtil.encryptDES(body, CharteredSecretKey);
            params = params.toUpperCase();
            log.info("XC-" + params);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        String sign = XieChengUtil.getCallbackSign(CharteredVenderId, timeStamp, params.length(), CharteredSecretKey);
        log.info("XC-" + sign);

        String action = "";
        switch (type) {
            case 3:{
                action="order/pushDriver";
            }
            break;
            case 7: {
                action = "order/pushComplete";
            }
            break;
            default: {
                return null;
            }
        }
        String url = charteredCallback + "/" + "day" + "-" + CharteredVenderId + "/" + action + "/" + orderId + "/" + timeStamp + "/" + sign;
        String result = null;
        try {
            log.info("XC-" + url);
            result = HttpRequestUtil.requestPostJson(url, params);
            log.info("XC-" + result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    private String sendToXC(int type, String orderId, String body) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStamp = sdf.format(System.currentTimeMillis());
        log.info("XC-" + body);

        String params = "";
        try {
            params = XieChengUtil.encodeDES(secretKey, body);
            params = params.toUpperCase();
            log.info("XC-" + params);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        String sign = XieChengUtil.getCallbackSign(venderId, timeStamp, params.length(), secretKey);
        log.info("XC-" + sign);

        String action = "";
        switch (type) {
            case 1: {
                //订单确认接口---携程现在不需要这个接口-以后再说
                action = "order/confirm";
                /*JSONObject json = new JSONObject();
                json.put("msgCode","OK");
                json.put("message","成功-携程现在不需要这个接口-以后再说");
                return json.toString();*/
            }
            //订单确认接口---携程现在不需要这个接口-以后再说
            break;
            case 2: {
                //司机信息推送接口
                action = "driver/push";
            }
            break;
            case 3: {
                //司机状态推送接口
                action = "driver/inplace";
            }
            break;
            case 4: {
                //订单完成接口
                action = "order/complete";
            }
            break;
            case 5: {
                //订单详情接口
                action = "order/detail";
            }
            break;
            default: {
                return null;
            }
        }
        String url = callback + "/" + channel + "-" + venderId + "/" + action + "/" + version + "/" + orderId + "/" + timeStamp + "/" + sign;
        String result = null;
        try {
            log.info("XC-" + url);
            result = HttpRequestUtil.requestPostJson(url, params);
            log.info("XC-" + result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    private Rv handleResult(String string) {
        XieChengResponse response = JSON.parseObject(string, XieChengResponse.class);
        if (response != null) {
            if (EXieChengResponseConstant.OK.getCode().equalsIgnoreCase(response.getMsgCode())) {
                return Rv.wrap();
            }
            log.info("携程同步错误：" + response.getMessage());
        }
        return Rv.error(EErrorCode.applyAmountOperateFailure);
    }

    /**
     * 获取一个默认接单账户-用于保证接单率
     *
     * @param personal
     * @return
     */
    private Map<String, Object> getDefaultDriver(OaCOrderPersonal personal) {
        Long officeId = personal.getOfficeId();
        Integer verType = personal.getVehicleType();
        OaSysOffice company = oaSysOfficeMapper.selectOne(Qw.create().eq(OaSysOffice.OFFICE_ID, personal.getOfficeId()));
        Map<String, Object> driverInfo = oaSysOfficeMapper.getCompanyDriver(officeId, verType);
        Object driverName = driverInfo.get("driverName");
        if (driverName == null) {
            log.info("Without driver -" + officeId + ":" + verType);
            return null;
        }
        Object vehColor = driverInfo.get("vehColor");
        String mvehColor = "无颜色";
        if (vehColor != null) {
            mvehColor = vehColor.toString();
        }
        /*Integer serviceScore = (Integer) driverInfo.get("serviceScore");
        double star = Math.ceil(serviceScore / 20.0);*/
        Map<String, Object> params = new HashMap<>();
        if (personal.getOrderType()==7){
            params.put("ctripOrderId", personal.getOrderNo());//同程订单号
            params.put("vendorOrderId", personal.getPersonalId());//供应商订单号
            params.put("driverId", driverInfo.get("driverId"));//司机姓名-这里是公司管理员名字
            params.put("driverName", company.getPrimaryPerson());//司机姓名-这里是公司管理员名字
            params.put("driverPhone", company.getPhone());//司机电话
            params.put("areaCode", "+86");//国家码
            params.put("vehicleNumber", driverInfo.get("vehNo"));//车牌号
            params.put("vehicleTypeBrand", driverInfo.get("vehType"));//车型品牌
            //params.put("vehicleBrandDetail", driverInfo.get("vehicleBrandDetail"));//车系
            params.put("vehicleColor", mvehColor);//车辆颜色
        }else{
            params.put("driverName", company.getPrimaryPerson());//司机姓名-这里是公司管理员名字
            params.put("driverPhone", company.getPhone());//司机电话
            params.put("driverPhoneCode", "+86");//国家码
            params.put("driverPhoneLangauge", "DR-ZH");//司机语言
            params.put("vehicleBrand", driverInfo.get("vehicleBrand"));//车型品牌
            params.put("vehicleBrandDetail", driverInfo.get("vehicleBrandDetail"));//车系
            params.put("vehicleColor", mvehColor);//车辆颜色
            params.put("vehicleNumber", driverInfo.get("vehNo"));//车牌号
            params.put("vendorOrderID", personal.getPersonalId());//供应商订单号
            params.put("ctripPurchaseOrderID", personal.getOrderNo());//同程订单号
        }

        //params.put("carType", driverInfo.get("vehType"));//车型
        //params.put("driverPhoneReal", company.getPhone());//司机真实手机号
        //params.put("driverLevel", String.format("%.1f", star));//司机星级（如：4.5   5.0）
        //params.put("driverLat", lat);//司机纬度
        //params.put("driverLng", lng);//司机经度
        //params.put("hasVirtual", 1);//车头接单传1 表示虚拟接单（1是  0否）
        return params;
    }
}
